package safrain.nodelet.pool;

import java.util.HashMap;
import java.util.Map;

import safrain.nodelet.exception.TypeNotRegisteredException;
import safrain.nodelet.structure.StructureService;

public class PoolService {
	/**
	 * 对象池依赖结构服务
	 */
	public StructureService structureService;

	private boolean autoRegister = true;

	private Map<Class<?>, ObjectPool> pools = new HashMap<Class<?>, ObjectPool>();
	private static final int DEFAULT_POOL_SIZE = 1000;

	@SuppressWarnings("unchecked")
	public <T> T get(Class<T> type) {
		ObjectPool pool = pools.get(type);
		if (pool == null) {
			if (autoRegister) {
				pool = register(type, DEFAULT_POOL_SIZE);
			} else {
				throw new TypeNotRegisteredException(type);
			}
		}
		return (T) pool.get();
	}

	public void recycle(Object object) {
		ObjectPool pool = pools.get(object.getClass());
		if (pool == null) {
			if (autoRegister) {
				pool = register(object.getClass(), DEFAULT_POOL_SIZE);
			} else {
				throw new TypeNotRegisteredException(object.getClass());
			}
		}
		pool.recycle(object);
	}

	public ObjectPool register(Class<?> type, int poolSize) {
		ObjectPool pool = new ObjectPool(structureService.getStructure(type), poolSize);
		pools.put(type, pool);
		return pool;
	}

	public ObjectPool registerSynchronized(Class<?> type, int poolSize) {
		ObjectPool pool = new SynchronizedPool(structureService.getStructure(type),
				poolSize);
		pools.put(type, pool);
		return pool;
	}

}
